import {
  reactiveMap,
  readonlyMap,
  shallowReadonlyMap,
  ReactiveFlags,
  readonly,
  reactive,
} from "./reactive";

import { track, trigger } from "./effect";
import { isObject } from "../utils/index";

function createGetter(isReadonly = false, isShallow = false) {
  return function get(target, key, receiver) {
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly;
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly;
    }

    const res = Reflect.get(target, key, receiver);
    console.log("get...", res);

    // 如果是只读参数,不需要追踪,因为无法触发,也就没有追踪的必要
    if (!isReadonly) {
      // 追踪
      track(target, "get", key);
    }

    // 不需要深度遍历,直接返回即可
    if (isShallow) {
      return res;
    }

    if (isObject(res)) {
      return isReadonly ? readonly(res) : reactive(res);
    }

    return res;
  };
}

export function createSetter() {
  return function set(target, key, newValue, receiver) {
    const oldValue = target[key];

    const result = Reflect.set(target, key, newValue, receiver);

    trigger(target, "set", key, newValue, oldValue);

    return result;
  };
}

const readonlyGetter = createGetter(true);
const shallowReadonlyGetter = createGetter(false, true);
const getter = createGetter();
const setter = createSetter();

export const readonlyHandler = {
  get: readonlyGetter,
  set(target, key) {
    console.warn(`只读对象不允许修改属性: ${String(key)}`);
    return true;
  },
};

export const mutablehandler = {
  get: getter,
  set: setter,
};

export const shallowReadonlyhandler = {
  get: shallowReadonlyGetter,
  set(target, key) {
    console.warn(`只读对象不允许修改属性:${String(key)}`);
    return true;
  },
};
